<template>
  <div class="home">
    <Filter :buttonLoading="buttonLoading" @search="search" />
    <Mention
      :mentionResultArr="mentionResultArr"
      @setMention="setMention"
      @setNoMention="setNoMention"
    />
    <div class="table" style="height: calc(100vh - 200px)">
      <el-auto-resizer>
        <template #default="{ height, width }">
          <el-table-v2 :columns="columns" :data="data" :width="width" :height="height" fixed />
        </template>
      </el-auto-resizer>
    </div>
  </div>
</template>

<script setup lang="tsx">
import { getRiflePrice, getMeleePrice, getPistolPrice } from '@/api/index';
import { ref } from 'vue';
import Filter from '@/component/Filter.vue';
import Mention from '@/component/Mention.vue';
import { Type, type Form, Source, OnLineState, Subtype } from '@/types/filter';
import { type ColumnItem } from '@/types/table';
import { ElButton } from 'element-plus';
import { copyToClipboard, notification } from '@/utils/tools';
import { PriceRes } from '@/types/api';
import { MentionResult, type TypeMention, type NoMention, OperateType } from '@/types/mention';
import config from '@/config';
const { statusOptions, subtypeOptions, soruceOptions } = config;
const buttonLoading = ref(false);

let searchData: Form = {
  source: [Source.rifle, Source.melee],
  type: Type.sell,
  onLineState: [OnLineState.ingame, OnLineState.online],
  subType: [Subtype.unrevealed],
  lessPrice: 25,
  overNum: 1,
  time: 5
};

const search = (form: Form) => {
  buttonLoading.value = true;
  searchData = form;
  getData(true);
};

// 提醒条件
const mentionArr = ref<TypeMention[]>([]);
// 提醒结果
const mentionResultArr = ref<MentionResult[]>([]);
//  不提醒列表
const noMentionArr = ref<NoMention[]>([]);

const setMention = (mention: TypeMention[]) => {
  mentionArr.value = mention;
};

// 设置不提醒列表
const setNoMention = (noMention: NoMention, type: OperateType) => {
  if (type === OperateType.add) {
    noMentionArr.value.push(noMention);
  } else {
    noMentionArr.value = noMentionArr.value.filter(
      item => item.ingameName !== noMention.ingameName
    );
  }
};

const message = (str: string) => {
  copyToClipboard(str);
  ElMessage.success('已复制到剪贴板');
};

const columns: ColumnItem[] = [
  {
    key: 'ingameName',
    dataKey: 'ingameName',
    title: '用户',
    width: 150
  },
  {
    key: 'reputation',
    dataKey: 'reputation',
    title: '声誉',
    width: 150
  },
  {
    key: 'source',
    dataKey: 'source',
    title: '物品',
    width: 150
  },
  {
    key: 'status',
    dataKey: 'status',
    title: '在线状态',
    width: 150
  },
  {
    key: 'platinum',
    dataKey: 'platinum',
    title: '价格',
    width: 150
  },
  {
    key: 'quantity',
    dataKey: 'quantity',
    title: '个数',
    width: 150
  },
  {
    key: 'subtype',
    dataKey: 'subtype',
    title: '是否揭示',
    width: 150
  },
  {
    key: 'chat',
    dataKey: 'chat',
    width: 150,
    title: '联系',
    // @ts-ignore
    cellRenderer: ({ cellData: chat }) => (
      <ElButton size="small" type="primary" onClick={message.bind(this, chat)}>
        联系他
      </ElButton>
    )
  }
];
const data = ref<Record<string, any>>([]);

const setNotification = (
  ingameName: string,
  source: string,
  quantity: string | number,
  platinum: string | number,
  subType: Subtype
) => {
  if (
    !noMentionArr.value.find(
      item =>
        item.ingameName === ingameName &&
        item.source === source &&
        item.quantity === quantity &&
        item.platinum === platinum &&
        subtypeOptions[item.subtype] === subType
    )
  ) {
    notification(
      '监控到有人出货了',
      `玩家（${ingameName}）；出物品（${source}） ；是否揭示：（${subType}）；个数（ ${quantity}）；价格（${platinum}p）`
    );
  }
};

// 处理提醒
const dealMention = (resItem: PriceRes['data'][0], source: Source) => {
  mentionArr.value.forEach(
    ({ subType, onLineState, overNum, source: mentionSource, lessPrice, id, isOn, valid }) => {
      if (
        onLineState.includes(resItem.user.status) &&
        subType.includes(resItem.subtype) &&
        resItem.platinum <= lessPrice &&
        resItem.quantity >= overNum &&
        mentionSource.includes(source) &&
        isOn &&
        valid
      ) {
        // 定义处理后的数据项
        const dealedDataItem: Record<string, any> = {};
        // 遍历列
        columns.forEach(i => {
          const options = {
            status: statusOptions[resItem?.user?.status],
            subtype: subtypeOptions[resItem?.subtype],
            source: soruceOptions[source],
            chat: {
              chatMsg: `/w ${resItem.user.ingameName} Hi! I want to buy: "${resItem.subtype} ${source} Riven Mod (Veiled)" for ${resItem.platinum} platinum. (warframe.market)`,
              data: {
                ingameName: resItem?.user?.ingameName,
                source: source,
                platinum: resItem?.platinum,
                quantity: resItem?.quantity,
                subtype: resItem?.subtype
              }
            }
          };
          // @ts-ignore
          dealedDataItem[i.dataKey] =
            // @ts-ignore
            options[i.dataKey] || resItem[i.dataKey] || resItem?.user?.[i.dataKey] || '0';
        });
        const result = mentionResultArr.value.find(item => {
          if (item.id === id) {
            const hasSameInfo = item.result.find(
              i =>
                i.ingameName === dealedDataItem.ingameName &&
                i.source === dealedDataItem.source &&
                i.platinum === dealedDataItem.platinum &&
                i.quantity === dealedDataItem.quantity &&
                i.subtype === dealedDataItem.subtype
            );
            // 有完全相同的信息就不要添加
            if (!hasSameInfo) {
              item.result.push(dealedDataItem);
              setNotification(
                dealedDataItem.ingameName,
                source,
                dealedDataItem.quantity,
                dealedDataItem.platinum,
                dealedDataItem.subtype
              );
            }
            return true;
          } else {
            return false;
          }
        });
        if (!result) {
          mentionResultArr.value.push({ id, result: [dealedDataItem] });
          setNotification(
            dealedDataItem.ingameName,
            source,
            dealedDataItem.quantity,
            dealedDataItem.platinum,
            dealedDataItem.subtype
          );
        }
      } else if (!isOn || !valid) {
        mentionResultArr.value = mentionResultArr.value.filter(item => item.id !== id);
      }
    }
  );
};

const dealData = (res: PriceRes['data'], source: Source) => {
  // 获取搜索数据
  const { onLineState, subType, overNum, lessPrice, type } = searchData;
  // 定义处理后的数据
  const dealedData: any[] = [];
  // 遍历价格信息
  res.forEach(item => {
    // 如果用户在线状态、子类型和数量都符合条件
    if (
      onLineState.includes(item.user.status) &&
      subType.includes(item.subtype) &&
      item.platinum <= lessPrice &&
      item.quantity >= overNum &&
      type === item.type
    ) {
      // 定义处理后的数据项
      const dealedDataItem: Record<string, any> = {};
      // 遍历列
      columns.forEach(i => {
        const options = {
          status: statusOptions[item?.user?.status],
          subtype: subtypeOptions[item?.subtype],
          source: soruceOptions[source],
          chat: `/w ${item.user.ingameName} Hi! I want to buy: "${item.subtype} ${source} Riven Mod (Veiled)" for ${item.platinum} platinum. (warframe.market)`
        };
        // @ts-ignore
        dealedDataItem[i.dataKey] =
          // @ts-ignore
          options[i.dataKey] || item[i.dataKey] || item?.user?.[i.dataKey] || '0';
      });
      dealMention(item, source);
      // 将处理后的数据项添加到处理后的数据中
      dealedData.push(dealedDataItem);
    }
  });
  // @ts-ignore
  dealedData.sort((prev, next) => prev.platinum - next.platinum);
  // 将处理后的数据赋值给data
  return dealedData;
};

const getDataOptions: Record<string, Function> = {
  getrifleData: getRiflePrice,
  getmeleeData: getMeleePrice,
  getpistolData: getPistolPrice
};

let timer: any = null;
const getData = (hasClick: boolean = false) => {
  const promiseAllArr: any[] = [];
  const promiseAllKey: Source[] = [];
  searchData.source.forEach((item, index) => {
    promiseAllArr.push(getDataOptions[`get${item}Data`]);
    promiseAllKey[index] = Source[item];
  });
  Promise.all(promiseAllArr.map(item => item()))
    .then(res => {
      const newRes: any[] = [];
      mentionResultArr.value = [];
      res.forEach((item, index) => {
        const result = dealData(item, promiseAllKey[index]);
        newRes.push(...result);
      });
      newRes.sort((prev, next) => prev.platinum - next.platinum);
      data.value = newRes;
      if (hasClick || buttonLoading.value) {
        buttonLoading.value = false;
        ElMessage.success('查询成功！');
      }
    })
    .finally(() => {
      timer && clearTimeout(timer);
      timer = setTimeout(() => {
        getData();
      }, searchData.time * 1000);
    });
};
</script>

<style scoped lang="less">
.home {
  padding: 60px;
}
</style>
